<template>
  <div class="screen-wrapper" ref="screenWrapper" :style="wrapperStyle">
    <slot></slot>
  </div>
</template>

<script setup>
import { ref, watch, onMounted, onBeforeUnmount, nextTick } from "vue";
import { useQuasar } from "quasar";
const $q = useQuasar();
const width = ref(1920);
const height = ref(1080);
const fullScreen = ref(false);
const autoScale = ref(true);
const selfAdaption = ref(true);
const delay = ref(500);
const boxStyle = ref({});
const wrapperStyle = ref({});
const screenWrapper = ref(null);
const currentWidth = ref(0);
const currentHeight = ref(0);
const originalWidth = ref(0);
const originalHeight = ref(0);
let onResize = null;
let observer = null;

const debounce = (fn, delay) => {
  let timer = null;
  return (...args) => {
    timer = setTimeout(
      () => {
        typeof fn === "function" && fn.apply(null, args);
        clearTimeout(timer);
      },
      delay > 0 ? delay : 100
    );
  };
};

const initSize = () => {
  return new Promise((resolve) => {
    // screenWrapper.value.parentNode.style.overflow = "hidden";
    screenWrapper.value.parentNode.scrollLeft = 0;
    screenWrapper.value.parentNode.scrollTop = 0;

    nextTick(() => {
      if (width.value && height.value) {
        currentWidth.value = width.value;
        currentHeight.value = height.value;
      } else {
        currentWidth.value = screenWrapper.value.clientWidth;
        currentHeight.value = screenWrapper.value.clientHeight;
      }

      if (!originalHeight.value || !originalWidth.value) {
        originalWidth.value = window.screen.width;
        originalHeight.value = window.screen.height;
      }

      resolve(true);
    });
  });
};

const updateSize = () => {
  if (currentWidth.value && currentHeight.value) {
    screenWrapper.value.style.width = `${currentWidth.value}px`;
    screenWrapper.value.style.height = `${currentHeight.value}px`;
  } else {
    screenWrapper.value.style.width = `${originalWidth.value}px`;
    screenWrapper.value.style.height = `${originalHeight.value}px`;
  }
};

const handleAutoScale = (scale) => {
  if (!autoScale.value) return;
  const domWidth = screenWrapper.value.clientWidth;
  const domHeight = screenWrapper.value.clientHeight;
  const currentWidth = $q.screen.width;
  const currentHeight = $q.screen.height;
  screenWrapper.value.style.transform = `scale(${scale},${scale}) `;
  let mx = Math.max((currentWidth - domWidth * scale) / 2, 0);
  let my = Math.max((currentHeight - domHeight * scale) / 2, 0);
  if (typeof autoScale.value === "object") {
    !autoScale.value.x && (mx = 0);
    !autoScale.value.y && (my = 0);
  }
  screenWrapper.value.style.margin = `${my}px ${mx}px`;
  console.log({
    mx,
    my,
    currentWidth,
    currentHeight,
    domWidth,
    domHeight,
    scale,
  });
};

const updateScale = () => {
  const currentWidth = $q.screen.width;
  const currentHeight = $q.screen.height;
  const realWidth = originalWidth.value;
  const realHeight = originalHeight.value;
  const widthScale = currentWidth / realWidth;
  const heightScale = currentHeight / realHeight;

  //打印以上6个变量
  console.log("currentWidth", currentWidth);
  console.log("currentHeight", currentHeight);
  console.log("realWidth", realWidth);
  console.log("realHeight", realHeight);
  console.log("widthScale", widthScale);
  console.log("heightScale", heightScale);

  if (fullScreen.value) {
    screenWrapper.value.style.transform = `scale(${widthScale},${heightScale})`;
    return false;
  }

  const scale = Math.min(widthScale, heightScale);
  handleAutoScale(scale);
};

const initMutationObserver = () => {
  const observer = new MutationObserver(() => {
    onResize();
  });

  observer.observe(screenWrapper.value, {
    attributes: true,
    attributeFilter: ["style"],
    attributeOldValue: true,
  });

  return observer;
};

const clearListener = () => {
  window.removeEventListener("resize", onResize);
};

const addListener = () => {
  window.addEventListener("resize", onResize);
};

const clearStyle = () => {
  screenWrapper.value.parentNode.style.overflow = "auto";
  screenWrapper.value.style = "";
};

const resize = async () => {
  if (!selfAdaption.value) {
    return;
  }
  await initSize();
  updateSize();
  updateScale();
};

onMounted(() => {
  onResize = debounce(() => {
    resize();
  }, delay.value);

  nextTick(() => {
    if (selfAdaption.value) {
      resize();
      addListener();
    }
  });
});

onBeforeUnmount(() => {
  clearListener();
  // observer.disconnect()
});

watch(selfAdaption, (val) => {
  if (val) {
    resize();
    addListener();
  } else {
    clearListener();
    clearStyle();
  }
});
</script>

<style scoped>
.screen-wrapper {
  transition-property: all;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 500ms;
  position: relative;
  z-index: 100;
  transform-origin: left top;
}
</style>
